﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IOT.DongleFlashTool.Utils
{
    public class BytesHelper
    {
        /// <summary>
        /// 转义数据，处理数据中出现的0x7e、0x7d
        /// </summary>
        /// <param name="dataBytes"></param>
        /// <returns></returns>
        public static byte[] EscapeDataBytes(byte[] dataBytes)
        {
            List<byte> dataBytesList = new List<byte>();
            dataBytesList.AddRange(dataBytes);
            int newBytesCount = 0;  // 新增的字节数，dataBytesList的下标需随时加入插入的新增字节数

            // 包首字节与尾字节不转义，跳过下标0与length-1
            for (int i = 1; i < dataBytes.Length - 1; i++)
            {
                if (dataBytes[i] == 0x7d)  // 0x7d时，在i+1除插入0x5d
                {
                    dataBytesList[i + newBytesCount] = 0x7d;
                    dataBytesList.Insert(i + 1 + newBytesCount, 0x5d);
                    newBytesCount++;
                }
                else if (dataBytes[i] == 0x7e)  // 0x7e时，替换0x7e为0x7d，并在i+1处插入0x5e
                {
                    dataBytesList[i + newBytesCount] = 0x7d;
                    dataBytesList.Insert(i + 1 + newBytesCount, 0x5e);
                    newBytesCount++;
                }
            }
            return dataBytesList.ToArray();
        }

        /// <summary>
        /// 反转义数据，还原出数据中出现的0x7e、0x7d
        /// </summary>
        /// <param name="dataBytes"></param>
        /// <returns></returns>
        public static byte[] UnEscapeDataBytes(byte[] dataBytes)
        {
            List<byte> dataBytesList = new List<byte>();
            dataBytesList.AddRange(dataBytes);

            for (int i = 1; i < dataBytesList.Count - 1; i++)
            {
                if (dataBytesList[i] == 0x7d)
                {
                    // 满足0x7d-0x5e，转义为0x7e，首位更改，第二位移除
                    if (dataBytesList[i + 1] == 0x5e)
                    {
                        dataBytesList[i] = 0x7e;  // 第一位直接改为0x7e
                        dataBytesList.RemoveAt(i + 1);  // 第二位移除
                    }
                    else if (dataBytesList[i + 1] == 0x5d)  // 满足0x7d-0x5d，转义为0x7d，首位不变，第二位移除
                    {
                        dataBytesList.RemoveAt(i + 1);  // 第二位移除
                    }
                }
            }
            return dataBytesList.ToArray();
        }

        /// <summary>
        /// 校验码是否符合
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static bool CheckParityByte(byte[] bytes)
        {
            byte parityByte = 0x00;

            // 去掉包头、包尾、上行标志位和校验位
            byte[] dataBytes = bytes.Skip(2).Take(bytes.Length - 4).ToArray();

            foreach (byte cbyte in dataBytes)
            {
                parityByte = (byte)((parityByte + cbyte) <= 255 ? (parityByte + cbyte) : (parityByte + cbyte) % 256);
            }

            return parityByte == bytes[bytes.Length - 2];
        }

        /// <summary>
        /// 反转MAC地址并转为HEX字符串
        /// </summary>
        /// <param name="macBytes"></param>
        /// <returns></returns>
        public static string ReverseMacAddressBytesToHexString(byte[] macBytes)
        {
            System.Text.Encoding chs = System.Text.Encoding.GetEncoding("UTF-8");
            string macAddress = chs.GetString(macBytes).Replace("\0", "").Trim();
            string[] macAddressHexStringArray = macAddress.Split('-');
            for (int i = macAddressHexStringArray.Length - 1; i >= 0; i--)
            {
                if (i == macAddressHexStringArray.Length - 1)
                {
                    macAddress = macAddressHexStringArray[i];
                }
                else
                {
                    macAddress += "-" + macAddressHexStringArray[i];
                }
            }
            return macAddress;
        }

        /// <summary>
        /// 将MAC地址字符串转为LCP需要的格式
        /// </summary>
        /// <param name="macAddress"></param>
        /// <returns></returns>
        public static string FormatLcpMacAddress(string macAddress)
        {
            macAddress = macAddress.Replace("-", "").ToUpper();  // 去"-"，转大写

            if (macAddress.Length > 16)  // 保留16位
            {
                macAddress = macAddress.Substring(0, 16);
            }
            else if (macAddress.Length < 16)  // 少于16位补Z
            {
                int loop = 16 - macAddress.Length;
                for (int i = 0; i < loop; i++)
                {
                    macAddress = "Z" + macAddress;
                }
            }
            return macAddress;
        }

        /// <summary>
        /// 将接收数据转为16进制字符串
        /// </summary>
        /// <param name="dataBates"></param>
        /// <returns></returns>
        public static string DataBytesToHexString(byte[] dataBytes, bool isContainsSpace = true)
        {
            string dataHexString = string.Empty;
            foreach (byte b in dataBytes)
            {
                if (isContainsSpace)
                {
                    dataHexString += b.ToString("X2") + " ";
                }
                else
                {
                    dataHexString += b.ToString("X2");
                }
            }
            return dataHexString;
        }

        /// <summary>
        /// 将接收数据转为16进制字符串(大写无空格)
        /// </summary>
        /// <param name="dataBates"></param>
        /// <returns></returns>
        public static string DataBytesToUpperHexString(byte[] dataBytes)
        {
            string dataHexString = string.Empty;
            foreach (byte b in dataBytes)
            {
                dataHexString += b.ToString("X2");
            }
            return dataHexString;
        }

        /// <summary>
        /// 将接收数据转为16进制字符串
        /// </summary>
        /// <param name="dataBates"></param>
        /// <returns></returns>
        public static byte[] HexStringToBytes(string dataBytesStr)
        {
            string[] temp = dataBytesStr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            byte[] buffer = new byte[temp.Length];
            for (int i = 0; i < temp.Length; i++)
            {
                buffer[i] = Convert.ToByte(temp[i], 16);
            }
            return buffer;
        }

        /// <summary>
        /// 字节反序
        /// </summary>
        /// <param name="bt"></param>
        /// <returns></returns>
        public static byte[] Reverse(dynamic bt)
        {
            byte[] resBt = covertFloatToByte(bt);
            resBt = resBt.Reverse().ToArray();
            return resBt;
        }

        /// <summary>
        /// 字符串转Byte数驵
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static byte[] retStrToByte(string str)
        {
            return System.Text.Encoding.Default.GetBytes(str);
        }

        /// <summary>
        /// 字节转字符串
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string retByteToStr(byte[] data)
        {
            return System.Text.Encoding.ASCII.GetString(data);
        }

        /// <summary>
        /// 浮点型转字节
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        private static byte[] covertFloatToByte(dynamic num)
        {
            int covNum = Convert.ToInt32(num);
            return BitConverter.GetBytes(covNum);
        }
    }
}
